﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Super.Common.WordAnalyzer
{
    /// <summary> 分词算法
    /// </summary>
    public class WordAnalyzer
    {
        /// <summary> 字符节点
        /// </summary>
        public class CharNode
        {
            /// <summary> 词结束.
            /// </summary>
            public bool IsEnd;

            /// <summary> 子字符.
            /// </summary>
            public Dictionary<char, CharNode> SubChar = new Dictionary<char, CharNode>();
        }

        private readonly CharNode _root = new CharNode();

        /// <summary> 增加词汇
        /// </summary>
        /// <param name="s"></param>
        public void AddWord(string s)
        {
            var sl = s.Length;

            var nc = _root;

            for (int i = 0; i < sl; i++)
            {
                //不存在则增加.
                if (!nc.SubChar.ContainsKey(s[i]))
                {
                    var t = new CharNode();
                    nc.SubChar.Add(s[i], t);
                    nc = t;
                }
                else
                {
                    nc = nc.SubChar[s[i]];
                }
            }

            nc.IsEnd = true;
        }

        /// <summary> 对 text 进行分词
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns> 
        public List<string> Analvzer(string text)
        {    
            var sl = text.Length;

            string word = "";

            CharNode nc = _root;

            //[词汇存在则不rollback, 如果词汇匹配失败,则回滚. ]
            var result = new List<string>();

            int rollbackInx = 0;

            for (int i = 0; i < sl; i++)
            {
                //判断char 是否在词库中存在
                if (nc.SubChar.TryGetValue(text[i], out nc))
                {
                    word += text[i];
                    if (nc.IsEnd) //完整词
                    {
                        result.Add(word);
                        rollbackInx = i;
                    }
                }
                else
                {
                    word = null;
                    nc = _root;
                    i = rollbackInx++;
                }
            }

            return result;
        }
    }
}
